/**
 *  list.h - Routines and structures for manipulating lists.
 *           Other data types that need to list each other can
 *           use those routines, instead of writing a set of routines
 *           for list operations.
 *
 *  Copyright (C) 2008-2009 ZhangHu
 *  All rights reserved.
 *  E-MAIL: anmnmnly@gmail.com
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef __LIST_H__
#define __LIST_H__

#include "include/types.h"


typedef struct slist_t {
    struct slist_t *next;
} slist_t;  /* Single List */


typedef struct list {
    struct list *prev;
    struct list *next;
} list_t;   /* Double-linked List */

/**
 * mac_find_entry - This macro is very important, and it comes from Linux.
 * @ptr: Pointer to host type.
 * @type: The name of host time
 * @member: A 'slist_t' or 'list_t' member in host type
 * @return: The entry of host type.
 *
 * @notes:
 */
#define mac_find_entry(ptr, type, member) \
((type *)((char_t*)(ptr)-(uword_t)(&((type *)0)->member)))


/* Initialize a node */
void list_node_single_init(slist_t *node);

/* Add a new node to a single list */
void add_node_single_list_head(slist_t *head, slist_t *pnew);

/* Delete a node from a single list */
slist_t *del_node_single_list(slist_t *head, slist_t *pdel);



/* Initialize a node */
void list_node_init(list_t *node);

/* Delete a new node to a Double-linked list */
list_t *del_node_list(list_t *head, list_t *pdel);

/* Add a node from a Double-linked list */
void add_node_list_rear(list_t *head, list_t *pnew);


#endif

